﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace WpfCmd
{
    /// <summary>
    /// Holds the history in the form of a list with an index
    /// </summary>
    public class CommandHistory
    {
        /// <summary>
        /// internal command history
        /// </summary>
        private List<String> list = new List<string>();

        public CommandHistory()
        {
            string path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);
            fullPath = string.Format("{0}\\CommandHistory.xml", path.TrimStart("file:\\\\".ToCharArray()));

            if (File.Exists(fullPath))
            {
                using (var stream = new StreamReader(fullPath))
                {
                    list = Deserialize<List<string>>(stream.ReadToEnd());
                }
            }
        }
        #region Enumeration Methods
        /// <summary>
        /// points somewhere in the list
        /// </summary>
        private int currentIndex = 0;

        /// <summary>
        /// Indicates if the GetNextCommand call will return the next command
        /// </summary>
        public bool HasNext
        {
            get { return currentIndex < (list.Count - 1); }
        }

        /// <summary>
        /// Indicates true if the GetPreviousCommand call will return any comaand
        /// </summary>
        public bool HasPrevious
        {
            get { return currentIndex > 0; }
        }

        /// <summary>
        /// Add the command to the hiostory
        /// </summary>
        /// <param name="command">the command</param>
        public void Add(string command)
        {
            if (list.Count > 0) currentIndex++;
            list.Add(command);
        }

        /// <summary>
        /// increases the index and returns the next command
        /// </summary>
        /// <returns>the command</returns>
        public string GetNext()
        {
            return list[++currentIndex];
        }

        /// <summary>
        /// Decrease the index and returns the command
        /// </summary>
        /// <returns>the command</returns>
        public string GetPrevious()
        {
            return list[--currentIndex];
        }

        #endregion

        private string fullPath;
        public void Save()
        {
            // There is no reason why I used 50 
            // If you think you can use more than 50 items, help yourself.
            int maxToSave = 50;

            if (list.Count == 0) return;
            if (list.Count > maxToSave)
                list.RemoveRange(maxToSave, list.Count - maxToSave);

            using (var outfile = new StreamWriter(fullPath))
            {
                outfile.Write(Serialize(list));
            }
        }

        /// <summary>
        /// Convert an instance to XML string
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public string Serialize<T>(T item)
        {

            var ms = new MemoryStream();
            var writer = new XmlTextWriter(ms, Encoding.Unicode);

            var serializer = new XmlSerializer(typeof(T));
            serializer.Serialize(writer, item);

            writer.Flush();
            ms.Position = 0;

            var reader = new StreamReader(ms);
            return reader.ReadToEnd();
        }

        /// <summary>
        /// Convert the XML string to an instance of an object
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public T Deserialize<T>(string xml)
        {
            var stream = new XmlTextReader(new StringReader(xml));
            var serializer = new XmlSerializer(typeof(T));
            return (T)serializer.Deserialize(stream);
        }


    }
}
